#include "updatechecker.h"
#include "configmanager.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QCryptographicHash>
#include <QStandardPaths>
#include <QDir>

UpdateChecker::UpdateChecker(QObject *parent)
    : QObject(parent)
    , m_networkManager(new QNetworkAccessManager(this))
    , m_silent(false)
    , m_tempFilePath("")
{
    if (!m_networkManager) {
        m_networkManager = new QNetworkAccessManager(this);
    }
}

UpdateChecker::~UpdateChecker()
{
    if (!m_tempFilePath.isEmpty() && QFile::exists(m_tempFilePath)) {
        QFile::remove(m_tempFilePath);
    }
}

void UpdateChecker::checkForUpdates(bool silent)
{

    m_silent = silent;

    // 使用新API规范的版本检查端点
    QString apiBase = ConfigManager::getApiBase();

    QUrl url;

    // 构建版本检查URL
    if (apiBase.contains("/auth/client/login")) {
        // 如果是登录端点，替换为版本检查端点
        QString versionUrl = apiBase.replace("/auth/client/login", "/client/version/check");
        url = QUrl(versionUrl);
    } else {
        // 否则使用相对路径
        url = QUrl("https://your-domain.com/api/client/version/check");
    }


    if (!url.isValid()) {
        if (!m_silent) {
            emit checkError("无效的服务器地址");
        }
        return;
    }

    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("Accept", "application/json");

    // 构建符合新API规范的请求载荷
    QJsonObject data;
    data["clientName"] = "LimeReader";    // 必填字段：固定值
    data["currentVersion"] = LimeReader::AppVersion::getAppVersion();  // 必填字段：客户端当前版本号


    // 添加平台信息
    QString platform;
#ifdef Q_OS_WIN
    platform = "windows";
    data["platform"] = platform;
#elif defined(Q_OS_MAC)
    platform = "macos";
    data["platform"] = platform;
#elif defined(Q_OS_LINUX)
    platform = "linux";
    data["platform"] = platform;
#else
    platform = "unknown";
    data["platform"] = platform;
#endif

    // 添加设备信息
    QJsonObject deviceInfo;
    deviceInfo["userAgent"] = LimeReader::AppVersion::getUserAgent();
    deviceInfo["os"] = getOSString();
    data["deviceInfo"] = deviceInfo;



    QJsonDocument doc(data);
    QByteArray jsonData = doc.toJson();



    QNetworkReply* reply = m_networkManager->post(request, jsonData);


    connect(reply, &QNetworkReply::finished,
            this, [this, reply]() { handleCheckResponse(reply); });
}

void UpdateChecker::handleCheckResponse(QNetworkReply* reply)
{

    reply->deleteLater();

    if (reply->error() != QNetworkReply::NoError) {
        if (!m_silent) {
            emit checkError(reply->errorString());
        }
        return;
    }

    QByteArray data = reply->readAll();

    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull()) {
        if (!m_silent) {
            emit checkError("服务器响应格式错误");
        }
        return;
    }

    QJsonObject obj = doc.object();

    // 检查响应是否成功
    bool hasSuccess = obj.contains("success");
    bool success = hasSuccess ? obj["success"].toBool() : false;

    if (hasSuccess) {
    }

    if (!hasSuccess || !success) {
        QString error = obj.contains("error") ? obj["error"].toString() : "UNKNOWN_ERROR";
        QString message = obj.contains("message") ? obj["message"].toString() : "版本检查失败";
        if (!m_silent) {
            emit checkError(message);
        }
        return;
    }

    // 检查是否有更新
    bool hasUpdateField = obj.contains("hasUpdate");
    bool hasUpdate = hasUpdateField ? obj["hasUpdate"].toBool() : false;


    if (!hasUpdate) {
        if (!m_silent) {
            emit noUpdateAvailable();
        }
        return;
    }


    // 解析新API规范的更新信息
    QString currentVersion = obj.value("currentVersion").toString();
    QString latestVersion = obj.value("latestVersion").toString();
    bool forceUpdate = obj.contains("forceUpdate") ? obj["forceUpdate"].toBool() : false;


    // 检查updateInfo对象
    bool hasUpdateInfo = obj.contains("updateInfo");
    QJsonObject updateInfo = hasUpdateInfo ? obj.value("updateInfo").toObject() : QJsonObject();

    if (hasUpdateInfo) {
    }

    QString downloadUrl = updateInfo.value("downloadUrl").toString();
    QString releaseNotes = updateInfo.contains("releaseNotes") ?
        updateInfo["releaseNotes"].toString() :
        (updateInfo.contains("releaseDate") ? updateInfo["releaseDate"].toString() : "");
    QString md5 = updateInfo.contains("hash") ?
        updateInfo["hash"].toString() :
        (updateInfo.contains("checksumMD5") ? updateInfo["checksumMD5"].toString() : "");
    QString updateSize = updateInfo.value("size").toString();



    // 发送更新可用信号
    emit updateAvailable(latestVersion, downloadUrl, releaseNotes, md5, updateSize);
}

void UpdateChecker::downloadUpdate(const QString& url, const QString& md5)
{

    QNetworkRequest request(url);
    QNetworkReply* reply = m_networkManager->get(request);

    // 设置MD5到reply的属性中，用于下载完成后验证
    reply->setProperty("md5", md5);

    connect(reply, &QNetworkReply::downloadProgress,
            this, &UpdateChecker::handleDownloadProgress);

    connect(reply, &QNetworkReply::finished,
            this, &UpdateChecker::handleDownloadFinished);

    // 準備臨時文件 - 根据平台选择合适的文件扩展名
    QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    QString fileName;
#ifdef Q_OS_WIN
    fileName = "LimeReader_Update.exe";
#elif defined(Q_OS_MAC)
    fileName = "LimeReader_Update.dmg";
#else
    fileName = "LimeReader_Update.tar.gz";
#endif

    m_tempFilePath = QDir(tempPath).filePath(fileName);
}

void UpdateChecker::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    double progressPercent = 0.0;
    if (bytesTotal > 0) {
        progressPercent = (double)bytesReceived / bytesTotal * 100.0;
    }


    emit downloadProgress(bytesReceived, bytesTotal);
}

void UpdateChecker::handleDownloadFinished()
{

    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    reply->deleteLater();


    if (reply->error() != QNetworkReply::NoError) {
        emit checkError(reply->errorString());
        return;
    }

    QByteArray data = reply->readAll();

    QFile file(m_tempFilePath);

    if (!file.open(QIODevice::WriteOnly)) {
        emit checkError(tr("无法保存更新文件"));
        return;
    }

    qint64 bytesWritten = file.write(data);
    file.close();


    // 驗證 MD5
    QString expectedMd5 = reply->property("md5").toString();

    if (!expectedMd5.isEmpty() && !verifyMd5(m_tempFilePath, expectedMd5)) {
        emit checkError(tr("文件校验失败，请重试"));
        return;
    }

    emit downloadFinished(m_tempFilePath);
}

bool UpdateChecker::verifyMd5(const QString& filePath, const QString& expectedMd5)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }
    
    QCryptographicHash hash(QCryptographicHash::Md5);
    if (!hash.addData(&file)) {
        return false;
    }
    
    QString actualMd5 = hash.result().toHex();
    return actualMd5.compare(expectedMd5, Qt::CaseInsensitive) == 0;
}

QString UpdateChecker::getOSString() const
{
    // 返回操作系统信息字符串
#ifdef Q_OS_WIN
    return QSysInfo::prettyProductName();
#elif defined(Q_OS_MAC)
    return QString("macOS %1").arg(QSysInfo::productVersion());
#elif defined(Q_OS_LINUX)
    return QSysInfo::prettyProductName();
#else
    return "Unknown";
#endif
} 